package main

import (
	"context"
	"errors"
	"fmt"
	"go.etcd.io/etcd/api/v3/v3rpc/rpctypes"
	"log"
	"strconv"
	"time"
)

func main() {
	defer CLI.Close()

	timeout := 3 * time.Second

	//etcd v3 uses gRPC for remote procedure calls. And clientv3 uses grpc-go to connect to etcd.
	//Make sure to close the client after using it.
	//If the client is not closed, the connection will have leaky goroutines.
	//To specify client request timeout, pass context.WithTimeout to APIs:
	{
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		resp, err := CLI.Put(ctx, "sample_key3", "sample_value")
		cancel()
		if err != nil {
			fmt.Println(err)
		}
		// use the response
		fmt.Println("put result:", resp)
		fmt.Println("put result.PrevKv:", resp.PrevKv)
	}
	fmt.Println("----------------")
	{
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		//resp, err := cli.Put(ctx, "", "") //必须指定 key
		resp, err := CLI.Put(ctx, "a", "") //必须指定
		cancel()
		if err != nil {
			switch {
			case errors.Is(err, context.Canceled):
				log.Fatalf("ctx is canceled by another routine: %v", err)
			case errors.Is(err, context.DeadlineExceeded):
				log.Fatalf("ctx is attached with a deadline is exceeded: %v", err)
			case errors.Is(err, rpctypes.ErrEmptyKey):
				log.Fatalf("client-side error: %v", err)
			default:
				log.Fatalf("bad cluster endpoints, which are not etcd servers: %v", err)
			}
		} else {
			fmt.Println("put result:", resp)
		}
	}

	for i := 0; i < 10; i++ {
		ctx, cancel := context.WithTimeout(context.Background(), timeout)
		resp, err := CLI.Put(ctx, string(rune('a'+i)), strconv.Itoa(i))
		cancel()
		if err != nil {
			panic(err)
		}
		fmt.Printf("put result- %d: %v\n", i, resp)

	}

}
